package com.fq.wechat.util;

import com.fq.wechat.action.WXAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

/**
 * MsgInvokeUtil: 根据不同的msg路由到WXAction中的不同方法中
 * @author jifang.
 * @since 2016/4/18 17:53.
 */
public class MsgInvokeUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(MsgInvokeUtil.class);

    private static final Class<?> action = WXAction.class;

    private static final Set<String> methods;

    static {
        Method[] declaredMethods = action.getDeclaredMethods();
        methods = new HashSet<>(declaredMethods.length);
        for (Method method : declaredMethods) {
            methods.add(method.getName());
        }
    }

    public static Object invoke(String msgKey, Object target, Object... args) {
        String methodName = composeMethodMame(msgKey);
        Class<?>[] paramTypes = new Class[args.length];
        for (int i = 0; i < args.length; ++i) {
            paramTypes[i] = args[i].getClass().getInterfaces()[0];
        }
        try {
            Method method = action.getDeclaredMethod(methodName, paramTypes);
            method.setAccessible(true);
            return method.invoke(target, args);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            LOGGER.error("method {} invoke error", methodName, e);
            throw new RuntimeException(e);
        }
    }

    private static String composeMethodMame(String msgKey) {
        String methodName = "do_" + msgKey;
        if (!methods.contains(methodName))
            methodName = "do_default";
        return methodName;
    }
}
